<template>
  <el-dialog
    v-bind="$attrs"
    :title="
      operationType === 'save'
        ? $t('flyparam.new_component')
        : $t('flyparam.update_component')
    "
    v-on="$listeners"
    @close="handleClose"
    @open="handleOpen"
  >
    <el-form
      ref="form"
      :model="form"
      :rules="rules"
      size="small"
      label-width="150px"
      @submit.native.prevent
    >
      <el-form-item :label="$t('flyparam.param_label')" prop="label">
        <el-input
          v-model="form.label"
          :maxlength="MAX_LENGTH.LABEL"
          @blur="() => (form.label = form.label.trim())"
        />
      </el-form-item>

      <el-form-item :label="$t('flyparam.component.param_key')" prop="key">
        <el-input
          v-model="form.key"
          :maxlength="MAX_LENGTH.KEY"
          @blur="() => (form.key = form.key.trim())"
        />
      </el-form-item>

      <el-form-item
        :label="$t('flyparam.component.param_type')"
        prop="valueType"
      >
        <el-select v-model="form.valueType" @change="handleValueTypeChange">
          <el-option label="String" :value="types.STRING" />
          <el-option label="Number" :value="types.NUMBER" />
          <el-option label="Hex" :value="types.HEX" />
          <el-option label="Boolean" :value="types.BOOLEAN" />
          <el-option label="File" :value="types.FILE" />
          <!--          <el-option label="Reference" :value="types.REFERENCE" />-->
          <el-option label="Time" :value="types.TIME" />
          <el-option label="Date" :value="types.DATE" />
          <el-option label="DateTime" :value="types.DATETIME" />
        </el-select>
      </el-form-item>

      <el-form-item
        v-if="[types.TIME, types.DATETIME, types.DATE].includes(form.valueType)"
        prop="formatter"
        :label="$t('flyparam.date_formatter')"
      >
        <el-select v-model="form.formatter" size="small" class="el-input">
          <div>
            <el-option
              v-for="format in dateFormatters[form.valueType]"
              :key="format"
              :label="format"
              :value="format"
            />
          </div>
        </el-select>
      </el-form-item>

      <el-form-item
        v-if="form.valueType === types.STRING"
        :label="$t('flyparam.max_length')"
        prop="maxLength"
        :rules="[
          {
            validator: validateMaxLength,
            maxLength: MAX_LENGTH[form.valueType]
          }
        ]"
      >
        <el-input
          v-model.number="form.maxLength"
          class="el-input__max-length"
          type="number"
          :max="MAX_LENGTH[form.valueType]"
        />
      </el-form-item>

      <el-form-item
        v-else-if="form.valueType === types.HEX"
        :label="$t('flyparam.max_length')"
        prop="maxLength"
        :rules="[
          {
            validator: validateMaxLength,
            maxLength: MAX_LENGTH[form.valueType]
          }
        ]"
      >
        <el-input
          v-model.number="form.maxLength"
          class="el-input__max-length"
          type="number"
          :max="MAX_LENGTH[form.valueType]"
        />
      </el-form-item>

      <el-form-item
        v-else-if="form.valueType === types.NUMBER"
        :label="$t('flyparam.max_length')"
        :rules="[
          {
            validator: validateMaxLength,
            maxLength: MAX_LENGTH[form.valueType]
          }
        ]"
        prop="maxLength"
      >
        <el-input
          v-model.number="form.maxLength"
          class="el-input__max-length"
          type="number"
          :max="MAX_LENGTH[form.valueType]"
        />
      </el-form-item>

      <el-form-item
        v-if="form.valueType !== types.BOOLEAN"
        :label="$t('flyparam.param_require')"
        prop="nullable"
      >
        <el-switch
          v-model="form.nullable"
          :active-value="0"
          :inactive-value="1"
        />
      </el-form-item>

      <el-form-item :label="$t('flyparam.component.category')" prop="category">
        <el-autocomplete
          v-model="form.category"
          :fetch-suggestions="getComponentCategorySet"
        />
      </el-form-item> </el-form
    ><template #footer>
      <div>
        <el-button size="small" @click="handleClose">{{
          $t('common.cancel')
        }}</el-button>
        <el-button
          size="small"
          type="primary"
          :loading="loading"
          @click="confirm"
          >{{
            operationType === 'save' ? $t('common.save') : $t('common.update')
          }}</el-button
        >
      </div></template
    >
  </el-dialog>
</template>

<script>
import { types, dateFormatters, MAX_LENGTH } from '../constant'
import {
  saveCommonComponent,
  updateCommonComponent,
  queryComponentCategorySet
} from '@/api/parameter'
import { validateInput, validateLabel } from '../validate'
import { i18n } from '@/lang'

export function validateMaxLength(rule, value, callback) {
  if (Number(value) > rule.maxLength) {
    this.form.maxLength = rule.maxLength
  } else if (Number(value) < 1) {
    this.form.maxLength = 1
  }
  callback()
}

export default {
  props: {
    component: {
      type: Object
    },
    operationType: {
      type: String,
      default: 'save'
    }
  },
  data() {
    return {
      types: Object.freeze(types),
      MAX_LENGTH: Object.freeze(MAX_LENGTH),
      dateFormatters: Object.freeze(dateFormatters),
      loading: false,
      form: {
        valueType: 1,
        label: '',
        key: '',
        maxLength: 255,
        nullable: 0,
        description: '',
        category: '',
        formatter: ''
      },
      rules: {
        label: [
          {
            required: true,
            message: i18n.t('common.please_input'),
            trigger: 'blur'
          },
          {
            validator: validateLabel
          }
        ],
        maxLength: [
          {
            required: true,
            message: i18n.t('common.please_input')
          }
        ],
        key: [
          {
            required: true,
            message: i18n.t('common.please_input'),
            trigger: 'blur'
          },
          {
            validator: validateInput
          }
        ],
        valueType: [
          {
            required: true,
            message: i18n.t('common.please_select'),
            trigger: 'blur'
          }
        ],
        category: [
          {
            required: true,
            message: i18n.t('common.please_input')
          },
          {
            max: MAX_LENGTH.CUSTOM_COMPONENT_CATEGORY,
            message: i18n.t('flyparam.length_exceeds')
          }
        ],
        formatter: [
          {
            required: true,
            message: i18n.t('flyparam.required2')
          }
        ]
      },
      categoryList: [],
      validateMaxLength: validateMaxLength.bind(this)
    }
  },
  computed: {},
  created() {
    // this.getComponentCategorySet('')
  },
  methods: {
    getComponentCategorySet(query, cb) {
      queryComponentCategorySet({ categoryLike: this.form.category })
        .then((res) => {
          this.categoryList = res
          cb(res.map((_) => ({ value: _ })))
        })
        .catch((err) => {
          this.$confirmError(err)
        })
    },
    handleOpen() {
      this.$nextTick(() => {
        if (this.component) {
          this.form = Object.assign(this.form, this.component)
        }
      })
    },
    handleClose() {
      this.$refs.form.resetFields()
      this.form.maxLength = 255
      this.$emit('update:model-value', false)
      this.$emit('update:component', {})
    },
    confirm() {
      this[this.operationType]()
    },
    save() {
      this.loading = true
      this.$refs['form'].validate((valid) => {
        if (valid) {
          saveCommonComponent({
            ...this.form,
            maxLength: this.form.maxLength || 1
          })
            .then((res) => {
              this.$message.success(this.$t('cmp.msg_saveSucceed'))
              this.$emit('confirm')
              this.handleClose()
            })
            .catch(this.$confirmError)
            .finally(() => {
              this.loading = false
            })
        } else {
          this.loading = false
          console.log('error submit!!')
          return false
        }
      })
    },
    update() {
      this.loading = true
      this.$refs['form'].validate((valid) => {
        if (valid) {
          updateCommonComponent(this.component.componentId, {
            ...this.form,
            maxLength: this.form.maxLength || 1
          })
            .then((res) => {
              this.$message.success(this.$t('page.update_success'))
              this.$emit('confirm')
              this.handleClose()
            })
            .catch(this.$confirmError)
            .finally(() => {
              this.loading = false
            })
        } else {
          this.loading = false
          console.log('error submit!!')
          return false
        }
      })
    },
    handleValueTypeChange(value) {
      const maxLengthMap = {
        [types.STRING]: 255,
        [types.NUMBER]: 2048,
        [types.HEX]: 2048
      }
      this.form.formatter = ''
      this.form.maxLength = maxLengthMap[value]
    }
  }
}
</script>

<style lang="scss" scoped>
.el-input__max-length {
  width: 212px;
}
</style>
